Annotation Processors

Ellen Spertus (spertus@google.com)

Background

Annotation processors are Java programs that produce an output or perform actions based on annotations (introduced in Java 1.5) that they find in Java source code.  The purpose of the App Inventor annotation processors is to produce information about the run-time components needed by different parts of the system.   For more information on  the files generated and how they are used, see the App Inventor Developer Overview.  Table 1 provides a summary, with links to more detailed information.  You can learn about the existing annotations from the Javadoc or from the document How to Add a Component.

Annotation processors

Files produced

Used by *

ComponentDescriptorGenerator

simple_components.json

Designer

LangDefXmlGenerator

ya_lang_def.xml

Blocks Editor

ComponentListGenerator

simple_components.txt

simple_components_permissions.json

Build server

DocumentationGenerator

component-doc.html

website

Table 1: Files produced by the annotation processors and where they are used.  
Links in the first column are to source code, and links in the second column are to further documentation.

Classes

Figure 1: Static UML class diagram for javax.annotation.processing.AbstractProcessor and ComponentProcessor.  Italics indicate abstract classes or methods.  Public members are indicated with plus signs (+) and protected members with pound signs (#).  Less important details (such as methods in AbstractProcessor that are not overridden) are omitted.

The abstract superclass of all of the annotation processors is ComponentProcessor.  It provides a concrete process() method as defined by its superclass javax.annotation.processing.AbstractProcessor (Figure 1), which processes the annotations and Javadoc comments in the component source code and creates and populates the protected instance variable components, a map from the fully-qualified name of each concrete component to a ComponentInfo, which represents the relevant information about the component using the inner classes shown in Figure 2.   Finally, process() calls ComponentProcessor.outputResults(), which subclasses must override.

Figure 2: Static UML class diagram for some of the inner classes of ComponentProcessing.  All fields are protected unless otherwise specified (+ for public, - for private).

Rather than duplicating information available elsewhere, the reader is referred to the detailed ComponentProcessor Javadoc for more information.

Currently, there are four concrete subclasses of ComponentProcessor, shown in Table 1.

Adding a new annotation

New annotations should be thoroughly discussed with the development team before implementation.  First, a consensus should be reached about the need for the annotation.  Second, the source file defining the annotation should be written, complete with Javadoc.  It should be similar to those in the directory components/com/google/appinventor/components/annotations.  To verify that it compiles and that the Javadoc is correct, build the javadoc target in the top-level directory and view the resulting Javadoc.  When satisfied with the results, the source code and/or Javadoc should be shared and discussed, along with some sample annotations for existing components.

In order for the annotation processors to recognize the new annotation, the following changes must be made to ComponentProcessor.java:

  1. It must be added to the private field SUPPORTED_ANNOTATION_TYPES in ComponentProcessor.java.
  2. The class ComponentProcessor.ComponentInfo must be modified to store the new information.
  3. One or more existing annotation processors must be modified to output (or otherwise make use of) the new information.

Adding a new annotation processor

The first step in adding a new annotation processor is viewing the output of the existing annotation generators to determine which to emulate or subclass.  Which you choose will likely depend on the formats in which data is output (text, html, or json) and which types of information are output (just the name of the component, complete information about each component, etc.).  The reader should view the sample output shown in the section Component Information Files in App Inventor Developer Overview.

Here are some points to keep in mind: